#pragma once
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#include <string.h>

#include "dua_conf.h"

enum {
    DUA_OK,
    DUA_ERROR,
    DUA_NO_MEM,
};


#define DUA_TANY        0x00
#define DUA_TBOOL       0x10
#define DUA_TNUMBER     0x20
#define DUA_TSTRING     0x30
#define DUA_TARRAY      0x40
#define DUA_TMAP        0x50
#define DUA_TCLASS      0x60
#define DUA_TFUNC       0x70
#define DUA_TCLOSURE    0x80
#define DUA_TSTACK      0x90

#define DUA_TINT        (DUA_TNUMBER | 0x01)
#define DUA_TLONG       (DUA_TNUMBER | 0x02)
#define DUA_TFLOAT      (DUA_TNUMBER | 0x03)
#define DUA_TDOUBLE     (DUA_TNUMBER | 0x04)

#define DUA_TSS         (DUA_TSTRING | 0x1)
#define DUA_TLS         (DUA_TSTRING | 0x2)


typedef struct DuaState DuaState;
typedef void* (*DuaAlloc)(void* ud,
        void* p, int type, size_t osz, size_t nsz);
typedef unsigned (*DuaFunc)(DuaState* D);


DUA_API DuaState*
duaNewState(DuaAlloc alloc, void*ud);

DUA_API int
duaCallFunc(DuaState* D, DuaFunc func, unsigned* nResult);

DUA_API void
duaCheckStack(DuaState* D, unsigned count);
DUA_API void
duaPushStringLen(DuaState* D, const char* str, size_t len);
#define duaPushString(D, S) duaPushStringLen((D), (S), strlen(S) + 1)
